Repository navigation
feat(io)!: multishot receive into the runtime's provided buffer ring - #149
Merged
Merged
Conversation
On Linux over io_uring a compio stream now receives with one armed multishot receive into the runtime's buffer pool instead of a submission per read. Received bytes are lent through the new `ReadOwned` trait or copied into the caller's buffer by `Read`, and each ring buffer goes back as soon as its bytes are consumed, so an idle connection holds none. A read that finds the ring dry receives into the caller's buffer and the next one arms again. A splice from the socket first moves the bytes already received, and `ReadAhead::stop_read_ahead` ends the receive for good and hands those bytes back; the kernel TLS switch uses it so the kernel starts at the right record. `StreamSocket` now requires both traits. Buffers are consumed whole: incremental consumption (IOU_PBUF_RING_INC) needs IORING_CQE_F_BUF_MORE, which compio does not report.
A connection's receive half is now `ReadOwned`. Bytes a stream lends are copied onto the end of the receive buffer and the stream's buffer goes back at once, so a connection reserves room only for bytes that arrived; a stream that lends nothing is read into the buffer's spare capacity as before.
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Linux, a compio stream now receives with one multishot receive into the runtime's provided buffer ring. One submission serves many reads, and a connection holds a buffer only from when bytes arrive until its reader is done with them.
ReadOwned::read_ownedlends the ring buffer (Received::Lent); dropping it returns the buffer. Streams with no ring (tokio, async-io, TLS halves) and an exhausted ring answerReadInstead, which takes the plainreadpath. h1 receives through it.ReadAhead::stop_read_aheadcancels and drains the armed receive. The kernel-TLS switch calls it so the bytes read past the last handshake record go to rustls instead of being lost, since the kernel can only decrypt what is still in the socket.StreamSocketnow also requiresReadOwned + ReadAhead.This uses compio's own buffer pool, one per runtime and so one per serving thread. It is correct without incremental consumption (
IOU_PBUF_RING_INC). Incremental consumption needsIORING_CQE_F_BUF_MORE, which compio does not expose yet (compio-rs/compio#1142). compio's default pool is 8 × 8 KiB, so servers have to size it on their runtime builder.New io tests run each read through a small ring and fail if it falls back. They cover one receive submission serving 64 KiB of reads, a connection reading more than the ring holds, a splice taking what was already received first, and stopping read-ahead. On Linux the io, h1 and default tls suites pass. The kernel-TLS switch needs the
tlsmodule, so only CI exercises it.Closes #124